<template>
  <!-- 使用绝对定位确保在全屏容器中也能显示 -->
  <div class="voice-notification-wrapper" :style="wrapperStyle">
    <transition-group
      name="voice-notification-fade"
      tag="div"
      class="voice-notification-container"
      :class="containerClass"
      :style="containerStyle"
    >
      <div
        v-for="notification in notifications"
        :key="notification.id"
        :class="[
          'voice-notification',
          `voice-notification--${notification.type}`,
          `voice-notification--${notification.position}`,
          notification.customClass
        ]"
        :style="getNotificationStyle(notification)"
        @mouseenter="pauseAutoClose(notification)"
        @mouseleave="resumeAutoClose(notification)"
        @click="handleClick(notification)"
      >
        <!-- 通知头部 -->
        <div class="voice-notification__header">
          <div class="voice-notification__title">
            <i :class="getIconClass(notification.type)" class="voice-notification__icon" />
            <span>{{ notification.title }}</span>
          </div>
          <i
            v-if="notification.showClose"
            class="voice-notification__close el-icon-close"
            @click.stop="close(notification.id)"
          />
        </div>

        <!-- 通知内容 -->
        <div class="voice-notification__content">
          <div v-if="notification.useHTML" v-html="notification.message" />
          <div v-else>{{ notification.message }}</div>

          <!-- 语音播报进度 -->
          <div v-if="notification.showVoiceProgress && notification.voiceProgress" class="voice-progress">
            <div class="voice-progress__text">
              播报进度: {{ notification.voiceProgress.current }}/{{ notification.voiceProgress.total }}
            </div>
            <el-progress
              :percentage="notification.voiceProgress.percentage"
              :stroke-width="6"
              :show-text="false"
              class="voice-progress__bar"
            />
          </div>
        </div>

        <!-- 自动关闭进度条 -->
        <div
          v-if="notification.duration > 0 && notification.showProgress"
          class="voice-notification__progress"
          :style="{ animationDuration: `${notification.duration}ms` }"
        />
      </div>
    </transition-group>
  </div>
</template>

<script>

export default {
  name: 'VoiceNotification',
  props: {
    // 容器位置
    position: {
      type: String,
      default: 'top-right',
      validator: (value) => [
        'top-right',
        'top-left',
        'bottom-right',
        'bottom-left',
        'top-center',
        'bottom-center'
      ].includes(value)
    },
    // 容器层级
    zIndex: {
      type: Number,
      default: 2147483647 // 使用最大 z-index 值
    },
    // 最大显示数量
    maxCount: {
      type: Number,
      default: 5
    },
    // 默认偏移量
    offset: {
      type: Number,
      default: 16
    },
    // 容器自定义类名
    containerClass: {
      type: String,
      default: ''
    },
    // 是否显示进度条
    showProgress: {
      type: Boolean,
      default: true
    },
    // 是否附加到全屏元素
    attachToFullscreen: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      notifications: [],
      fullscreenElement: null,
      isInFullscreen: false
    }
  },
  computed: {
    containerStyle() {
      return {
        'z-index': this.zIndex
      }
    },
    wrapperStyle() {
      // 如果在全屏模式中，将 wrapper 定位到全屏元素内
      if (this.isInFullscreen && this.fullscreenElement) {
        return {
          position: 'absolute',
          top: '0',
          left: '0',
          width: '100%',
          height: '100%',
          'z-index': this.zIndex
        }
      }
      return {
        'z-index': this.zIndex
      }
    }
  },
  mounted() {
    this.initFullscreenDetection()
    // this.appendToBody()
  },
  beforeDestroy() {
    this.cleanup()
  },
  methods: {
    // 初始化全屏检测
    initFullscreenDetection() {
      // 监听全屏变化
      document.addEventListener('fullscreenchange', this.handleFullscreenChange)
      document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange)
      document.addEventListener('mozfullscreenchange', this.handleFullscreenChange)
      document.addEventListener('MSFullscreenChange', this.handleFullscreenChange)

      // 初始检查
      this.checkFullscreenState()
    },

    // 处理全屏变化
    handleFullscreenChange() {
      this.checkFullscreenState()
    },

    // 检查全屏状态
    checkFullscreenState() {
      const fullscreenElement =
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement

      this.isInFullscreen = !!fullscreenElement
      this.fullscreenElement = fullscreenElement

      if (this.isInFullscreen && this.attachToFullscreen) {
        this.attachToFullscreenElement(fullscreenElement)
      } else {
        this.attachToBody()
      }
    },

    // 附加到全屏元素
    attachToFullscreenElement(element) {
      const wrapper = this.$el
      if (wrapper && wrapper.parentNode !== element) {
        // 如果已经在 body 上，先移除
        if (wrapper.parentNode === document.body) {
          document.body.removeChild(wrapper)
        }
        element.appendChild(wrapper)
      }
    },

    // 附加到 body
    attachToBody() {
      const wrapper = this.$el
      if (wrapper && wrapper.parentNode !== document.body) {
        // 如果已经在其他元素上，先移除
        if (wrapper.parentNode && wrapper.parentNode !== document.body) {
          wrapper.parentNode.removeChild(wrapper)
        }
        document.body.appendChild(wrapper)
      }
    },

    // 清理资源
    cleanup() {
      // 移除事件监听
      document.removeEventListener('fullscreenchange', this.handleFullscreenChange)
      document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange)
      document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange)
      document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange)

      // 清理所有定时器
      this.notifications.forEach(notification => {
        if (notification.timer) {
          clearTimeout(notification.timer)
        }
      })
      this.notifications = []
    },

    // 显示通知
    show(options) {
      const id = `voice_notification_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`

      const notification = {
        id,
        title: options.title || '语音播报',
        message: options.message || '',
        type: options.type || 'info',
        duration: options.duration ?? 4500,
        position: options.position || this.position,
        showClose: options.showClose !== false,
        offset: options.offset || this.offset,
        zIndex: options.zIndex || this.zIndex,
        customClass: options.customClass || '',
        useHTML: options.dangerouslyUseHTMLString || false,
        showProgress: options.showProgress !== false,
        showVoiceProgress: options.showVoiceProgress || false,
        voiceProgress: options.voiceProgress || null,
        onClose: options.onClose,
        onClick: options.onClick,
        // 内部状态
        timer: null,
        closed: false,
        paused: false
      }

      // 如果超过最大数量，移除最早的通知
      if (this.notifications.length >= this.maxCount) {
        this.close(this.notifications[0].id)
      }

      this.notifications.push(notification)

      // 自动关闭
      if (notification.duration > 0) {
        this.startAutoClose(notification)
      }

      return id
    },

    // 语音播报专用通知
    voiceBroadcast(options) {
      const defaultOptions = {
        title: '语音播报',
        type: 'info',
        duration: 3000,
        showVoiceProgress: false,
        showClose: true,
        position: 'top-center'
      }

      return this.show({ ...defaultOptions, ...options })
    },

    // 语音播报进度通知
    voiceProgress(options) {
      const { current, total, message } = options
      const percentage = total > 0 ? Math.round((current / total) * 100) : 0

      return this.voiceBroadcast({
        message: message || `正在播报第 ${current} 条，共 ${total} 条`,
        voiceProgress: {
          current,
          total,
          percentage
        },
        duration: 0, // 不自动关闭
        showClose: true,
        showVoiceProgress: true
      })
    },

    // 语音播报开始通知
    voiceStart(message = '开始语音播报') {
      return this.voiceBroadcast({
        message,
        type: 'success',
        duration: 2000
      })
    },

    // 语音播报结束通知
    voiceEnd(message = '语音播报完成') {
      return this.voiceBroadcast({
        message,
        type: 'success',
        duration: 3000
      })
    },

    // 语音播报错误通知
    voiceError(message = '语音播报失败') {
      return this.voiceBroadcast({
        message,
        type: 'error',
        duration: 5000,
        showClose: true
      })
    },

    // 关闭通知
    close(id) {
      const notification = this.notifications.find(item => item.id === id)
      if (notification) {
        this.clearAutoClose(notification)

        // 触发关闭回调
        if (typeof notification.onClose === 'function') {
          notification.onClose()
        }

        // 标记为已关闭，等待动画结束后移除
        notification.closed = true
        setTimeout(() => {
          const index = this.notifications.findIndex(item => item.id === id)
          if (index > -1) {
            this.notifications.splice(index, 1)
          }
        }, 300)
      }
    },

    // 关闭所有通知
    closeAll() {
      this.notifications.forEach(notification => {
        this.clearAutoClose(notification)
      })
      this.notifications = []
    },

    // 更新通知
    update(id, options) {
      const notification = this.notifications.find(item => item.id === id)
      if (notification) {
        Object.assign(notification, options)

        // 如果更新了 duration，重新设置定时器
        if (options.duration !== undefined) {
          this.clearAutoClose(notification)
          if (options.duration > 0) {
            this.startAutoClose(notification)
          }
        }
      }
    },

    // 更新语音播报进度
    updateVoiceProgress(id, current, total, message) {
      const percentage = total > 0 ? Math.round((current / total) * 100) : 0
      this.update(id, {
        voiceProgress: {
          current,
          total,
          percentage
        },
        ...(message && { message })
      })
    },

    // 开始自动关闭计时
    startAutoClose(notification) {
      if (!notification.paused && notification.duration > 0) {
        notification.timer = setTimeout(() => {
          this.close(notification.id)
        }, notification.duration)
      }
    },

    // 清除自动关闭计时
    clearAutoClose(notification) {
      if (notification.timer) {
        clearTimeout(notification.timer)
        notification.timer = null
      }
    },

    // 暂停自动关闭（鼠标悬停时）
    pauseAutoClose(notification) {
      notification.paused = true
      this.clearAutoClose(notification)
    },

    // 恢复自动关闭（鼠标离开时）
    resumeAutoClose(notification) {
      notification.paused = false
      this.startAutoClose(notification)
    },

    // 获取通知样式
    getNotificationStyle(notification) {
      const style = {
        'z-index': notification.zIndex
      }

      return style
    },

    // 获取图标类名
    getIconClass(type) {
      const iconMap = {
        success: 'el-icon-success',
        warning: 'el-icon-warning',
        error: 'el-icon-error',
        info: 'el-icon-info'
      }
      return `voice-notification__icon--${type} ${iconMap[type] || iconMap.info}`
    },

    // 处理点击事件
    handleClick(notification) {
      if (typeof notification.onClick === 'function') {
        notification.onClick()
      }
    }
  }
}
</script>

<style scoped lang="scss">
.voice-notification-wrapper {
  // 包装器样式 - 使用 fixed 定位确保在全屏中可见
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;

  // 确保在全屏元素中层级最高
  :fullscreen & {
    z-index: 2147483647;
  }

  :-webkit-full-screen & {
    z-index: 2147483647;
  }

  :-moz-full-screen & {
    z-index: 2147483647;
  }

  :-ms-fullscreen & {
    z-index: 2147483647;
  }
}

.voice-notification-container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;

  // 不同位置的定位
  .voice-notification {
    position: absolute;
    width: 380px;
    padding: 16px;
    box-sizing: border-box;
    border-radius: 8px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    background-color: #fff;
    border-left: 4px solid #409EFF;
    pointer-events: all;
    transition: all 0.3s;

    // 位置样式
    &--top-right {
      top: 16px;
      right: 16px;
    }

    &--top-left {
      top: 16px;
      left: 16px;
    }

    &--bottom-right {
      bottom: 16px;
      right: 16px;
    }

    &--bottom-left {
      bottom: 16px;
      left: 16px;
    }

    &--top-center {
      top: 16px;
      left: 50%;
      transform: translateX(-50%);
    }

    &--bottom-center {
      bottom: 16px;
      left: 50%;
      transform: translateX(-50%);
    }
  }

  // 不同类型样式
  .voice-notification--success {
    border-left-color: #67c23a;

    .voice-notification__icon--success {
      color: #67c23a;
    }
  }

  .voice-notification--warning {
    border-left-color: #e6a23c;

    .voice-notification__icon--warning {
      color: #e6a23c;
    }
  }

  .voice-notification--error {
    border-left-color: #f56c6c;

    .voice-notification__icon--error {
      color: #f56c6c;
    }
  }

  .voice-notification--info {
    border-left-color: #909399;

    .voice-notification__icon--info {
      color: #909399;
    }
  }

  // 组件内部结构样式
  .voice-notification__header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 8px;
  }

  .voice-notification__title {
    display: flex;
    align-items: center;
    font-weight: 600;
    font-size: 16px;
    color: #303133;
    line-height: 1.4;
  }

  .voice-notification__icon {
    margin-right: 8px;
    font-size: 16px;
  }

  .voice-notification__close {
    font-size: 14px;
    color: #c0c4cc;
    cursor: pointer;
    transition: color 0.2s;

    &:hover {
      color: #909399;
    }
  }

  .voice-notification__content {
    font-size: 14px;
    color: #606266;
    line-height: 1.5;
    word-wrap: break-word;
  }

  // 语音播报进度样式
  .voice-progress {
    margin-top: 12px;

    .voice-progress__text {
      font-size: 12px;
      color: #909399;
      margin-bottom: 6px;
    }

    .voice-progress__bar {
      ::v-deep .el-progress-bar {
        padding-right: 0;
      }
    }
  }

  .voice-notification__progress {
    position: absolute;
    bottom: 0;
    left: 0;
    width: 100%;
    height: 3px;
    background: linear-gradient(90deg, transparent, rgba(0, 0, 0, 0.1));
    animation: voice-progress-bar linear forwards;

    // 不同类型进度条颜色
    .voice-notification--success & {
      background: linear-gradient(90deg, transparent, rgba(103, 194, 58, 0.3));
    }

    .voice-notification--warning & {
      background: linear-gradient(90deg, transparent, rgba(230, 162, 60, 0.3));
    }

    .voice-notification--error & {
      background: linear-gradient(90deg, transparent, rgba(245, 108, 108, 0.3));
    }

    .voice-notification--info & {
      background: linear-gradient(90deg, transparent, rgba(144, 147, 153, 0.3));
    }
  }
}

// 动画定义
.voice-notification-fade-enter-active,
.voice-notification-fade-leave-active {
  transition: all 0.3s;
}

.voice-notification-fade-enter {
  opacity: 0;
  transform: translateX(100%);

  .voice-notification--top-left &,
  .voice-notification--bottom-left & {
    transform: translateX(-100%);
  }

  .voice-notification--top-center &,
  .voice-notification--bottom-center & {
    transform: translateX(-50%) translateY(-20px);
  }
}

.voice-notification-fade-leave-to {
  opacity: 0;
  transform: translateX(-100%);

  .voice-notification--top-right &,
  .voice-notification--bottom-right & {
    transform: translateX(100%);
  }

  .voice-notification--top-center &,
  .voice-notification--bottom-center & {
    transform: translateX(-50%) translateY(-20px);
  }
}

// 进度条动画
@keyframes voice-progress-bar {
  from {
    width: 100%;
  }
  to {
    width: 0%;
  }
}

// 全屏模式兼容 - 增强版
:fullscreen .voice-notification-wrapper,
:-webkit-full-screen .voice-notification-wrapper,
:-moz-full-screen .voice-notification-wrapper,
:-ms-fullscreen .voice-notification-wrapper {
  z-index: 2147483647 !important;
}

// 响应式调整
@media (max-width: 768px) {
  .voice-notification-container .voice-notification {
    width: calc(100vw - 32px);
    margin: 0 16px;

    &--top-right,
    &--top-left,
    &--bottom-right,
    &--bottom-left {
      left: 16px;
      right: 16px;
      transform: none;
    }
  }
}

// 高对比度模式支持
@media (prefers-contrast: high) {
  .voice-notification {
    border: 2px solid #303133;
  }
}

// 减少动画模式支持
@media (prefers-reduced-motion: reduce) {
  .voice-notification-fade-enter-active,
  .voice-notification-fade-leave-active {
    transition: none;
  }

  .voice-notification__progress {
    animation: none;
  }
}
</style>
